package com.skivingcloud.admin.sys.service.impl;

import com.skivingcloud.admin.sys.entity.SysOrg;
import com.skivingcloud.admin.sys.entity.SysStation;
import com.skivingcloud.admin.sys.entity.SysStationMenu;
import com.skivingcloud.admin.sys.entity.SysUserStation;
import com.skivingcloud.admin.sys.entity.User;
import com.skivingcloud.admin.sys.mapper.SysOrgMapper;
import com.skivingcloud.admin.sys.mapper.SysStationMapper;
import com.skivingcloud.admin.sys.mapper.SysStationMenuMapper;
import com.skivingcloud.admin.sys.mapper.SysUserStationMapper;
import com.skivingcloud.admin.sys.service.ISysOrgService;
import com.skivingcloud.common.contants.Constant;
import com.skivingcloud.common.utils.ElTreeUtils;
import com.skivingcloud.common.utils.TreeUtils;
import com.skivingcloud.common.utils.UuidUtil;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 组织机构表 服务实现类
 * </p>
 *
 * @author skivingcloud
 * @since 2022-01-29
 */
@Service
public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> implements ISysOrgService {

	@Autowired
	private SysStationMapper sysStationMapper;
	@Autowired
	private SysStationMenuMapper sysStationMenuMapper;
	@Autowired
	private SysUserStationMapper sysUserStationMapper;
	
	/**
	 * 根据租户获取机构树
	 * 
	 * @param tenantId
	 * @return
	 * @throws Exception
	 */
	@Override
	@Cacheable(value = "orgs", key = "'allList:' + #tenantId") // 缓存
	public List<TreeUtils> getAllOrgTreeUtils(String tenantId) throws Exception {
		QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<SysOrg>();
		queryWrapper.eq("tenant_id", tenantId);
		queryWrapper.orderByAsc("ordernum");
		List<SysOrg> list = this.baseMapper.selectList(queryWrapper);
		List<TreeUtils> treeList = TreeUtils.getTreeList(list, "id", "parentId", "orgName", null, null);
		return treeList;
	}

	/**
	 * 获取全量机构树
	 * 
	 * @return
	 * @throws Exception
	 */
	@Override
	@Cacheable(value = "orgs", key = "'allList'") // 缓存
	public List<TreeUtils> getAllOrgTreeUtils() throws Exception {
		QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<SysOrg>();
		queryWrapper.orderByAsc("ordernum");
		List<SysOrg> list = this.baseMapper.selectList(queryWrapper);
		List<TreeUtils> treeList = TreeUtils.getTreeList(list, "id", "parentId", "orgName", null, null);
		return treeList;
	}

	/**
	 * 新增机构
	 * 
	 * @param org
	 * @param user
	 */
	@Override
	@CacheEvict(value = "orgs", allEntries = true)
	@Transactional(rollbackFor = Exception.class)
    public void addOrg(SysOrg org, User user) {
		LocalDateTime nowDate = LocalDateTime.now();
		if (org.getParentId() == null || "".equals(org.getParentId())) {
			// 没有上级的将上级编号设置为0，将级别设置为1
			org.setOrgLevel(1);
			org.setParentId("0");
		}
		if (!"0".equals(org.getParentId())) {
			// 将上级isParent 设置为1，即是父节点
			SysOrg parent = this.baseMapper.selectById(org.getParentId());
			if (parent != null) {
				parent.setIsParent(Constant.COMMON_YES_OR_NO_YES);
				org.setOrgLevel(parent.getOrgLevel() + 1);
				org.setTenantId(parent.getTenantId());
				this.baseMapper.updateById(parent);
			}
		}
		org.setId(UuidUtil.get32UUID());
		org.setIsParent(Constant.COMMON_YES_OR_NO_NO);
		org.setVersion(0);
		org.setCreater(user.getId());
		org.setCreateTime(nowDate);
		org.setModUser(user.getId());
		org.setModTime(nowDate);
		this.baseMapper.insert(org);
	}

	/**
	 * 修改机构
	 * 
	 * @param org
	 * @param user
	 */
	@Override
	@CacheEvict(value = "orgs", allEntries = true)
	@Transactional(rollbackFor = Exception.class)
    public void updateOrg(SysOrg org, User user) {
		LocalDateTime nowDate = LocalDateTime.now();
		SysOrg orgNew = this.baseMapper.selectById(org.getId());
		SysOrg parent = this.baseMapper.selectById(org.getParentId());
		if (parent != null) {
			// 根据上级级别重新设置当前级别
			orgNew.setOrgLevel(parent.getOrgLevel() + 1);
		}
		orgNew.setVersion(orgNew.getVersion() + 1);
		orgNew.setModTime(nowDate);
		orgNew.setModUser(user.getUsername());
		orgNew.setOrdernum(org.getOrdernum());
		orgNew.setOrgName(org.getOrgName());
		orgNew.setShortName(org.getShortName());
		orgNew.setOrgStatus(org.getOrgStatus());
		orgNew.setOrgType(org.getOrgType());
		orgNew.setOrgRank(org.getOrgRank());
		orgNew.setOrgCode(org.getOrgCode());
		this.baseMapper.updateById(orgNew);
	}

	/**
	 * 删除机构
	 * 
	 * @param id
	 * @param user
	 */
	@Override
	@CacheEvict(value = "orgs", allEntries = true)
	@Transactional(rollbackFor = Exception.class)
    public void deleteById(String id, User user) {
		// 删除机构下挂的岗位、岗位权限、岗位用户信息
		QueryWrapper<SysStation> staqueryWrapper = new QueryWrapper<SysStation>();
		staqueryWrapper.eq("org_id", id);
		List<SysStation> stations = sysStationMapper.selectList(staqueryWrapper);
		if (!stations.isEmpty()) {
			List<String> stationIds = stations.stream().map(c -> c.getId()).collect(Collectors.toList());
			sysStationMapper.deleteBatchIds(stationIds);
			QueryWrapper<SysStationMenu> staMenuqueryWrapper = new QueryWrapper<SysStationMenu>();
			staMenuqueryWrapper.in("station_id", stationIds);
			sysStationMenuMapper.delete(staMenuqueryWrapper);
			QueryWrapper<SysUserStation> userStaqueryWrapper = new QueryWrapper<SysUserStation>();
			userStaqueryWrapper.in("station_id", stationIds);
			sysUserStationMapper.delete(userStaqueryWrapper);
		}
		// 删除机构信息
		this.baseMapper.deleteById(id);
	}

	/**
	 * 根据租户获取机构树
	 * 
	 * @param tenantId
	 * @return
	 * @throws Exception
	 */
	@Override
	// @Cacheable(value = "orgs", key = "'allList:' + #tenantId") // 缓存
	public List<ElTreeUtils> getAllOrgTreeUtilsEl(String tenantId) throws Exception {
		QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<SysOrg>();
		queryWrapper.eq("tenant_id", tenantId);
		queryWrapper.orderByAsc("ordernum");
		List<SysOrg> list = this.baseMapper.selectList(queryWrapper);
		List<ElTreeUtils> treeList = ElTreeUtils.getTreeList(list, "id", "parentId", "orgName", null, null);
		return treeList;
	}

}
